package login

import (
	"go_server/game_server/api/service/build"
	"go_server/game_server/dao/role_dao"
	"go_server/game_server/dao/user_dao"
	"go_server/game_server/event_manager"
	"go_server/game_server/event_manager/event_data/event_impl"
	"go_server/game_server/initializer/server_data_init"
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/game_server/world_manager"
	"go_server/zinx/zconf"
	"go_server/zinx/ziface"
	"go_server/zinx/zlog"
	"go_server/zinx/znet"
	"go_server/zinx/zutils"
)

type loginApi struct {
	znet.BaseRouter
}

func (*loginApi) Handle(request ziface.IRequest) {
	msg := &pb.LoginAuthC2S{}
	if !util.PBParseRet(request, msg) {
		return
	}

	uID := msg.GetUid()
	if zutils.IsEmpty(uID) {
		zlog.Error("收到客户端的UID为空")
		return
	}

	var roleId int64 = 0
	userInfo := user_dao.GetUserByUid(uID)
	conn := request.GetConnection()

	accountKickOut := false

	if userInfo == nil {
		server_data_init.ServerData.RoleIDLock.Lock()
		server_data_init.ServerData.ServerInf.RoleSequence++
		ID := server_data_init.ServerData.ServerInf.RoleSequence
		roleId = int64(zconf.GlobalObject.Id*100000 + ID)
		server_data_init.ServerData.RoleIDLock.Unlock()
		defer func(roleId int64) {
			user_dao.NewUserData(uID, roleId, conn.RemoteAddrString())
			role_dao.NewRole(uID, roleId)

			event_manager.EventManagerObj.FireEventData(event_impl.NewRoleCreateEvent(conn))
		}(roleId)
	} else {
		roleId = userInfo.RoleId
		playerConn := world_manager.WorldMgrObj.GetPlayerConn(roleId)
		if playerConn != nil {
			kickOut := &pb.LoginKickedS2C{
				Code: pb.ErrorCodeManager_ACCOUNT_LOGIN_KICK_OUT,
			}
			playerConn.SendBuffPBMsg(uint32(pb.ProtocolManager_LoginKicked), kickOut)
			playerConn.RemoveOnConnStop()
			playerConn.RemoveProperty("roleId")
			world_manager.WorldMgrObj.RemovePlayerConn(roleId)
			playerConn.Stop()
			accountKickOut = true
		}
	}

	conn.SetProperty("roleId", roleId)
	if !accountKickOut {
		build.BuildLoginInit(roleId)
	}

	loginEvent := event_impl.NewRoleLoginEvent(conn)
	event_manager.EventManagerObj.FireEventData(loginEvent)

	data := &pb.LoginAuthS2C{
		RoleId: roleId,
	}
	conn.SendBuffPBMsg(uint32(pb.ProtocolManager_LoginAuth), data)
	world_manager.WorldMgrObj.AddPlayerConn(roleId, conn)
}

func KickOutPlayer(roleId int64) bool {
	kickOut := &pb.LoginKickedS2C{
		Code: pb.ErrorCodeManager_ACCOUNT_UNUSUAL,
	}
	playerConn := world_manager.WorldMgrObj.GetPlayerConn(roleId)
	if playerConn == nil {
		return false
	}
	playerConn.SendBuffPBMsg(uint32(pb.ProtocolManager_LoginKicked), kickOut)
	playerConn.Stop()
	return true
}

func KickOutAllPlayer() bool {
	kickOut := &pb.LoginKickedS2C{
		Code: pb.ErrorCodeManager_SERVER_MAINTAIN,
	}
	playerArr := world_manager.WorldMgrObj.GetOnlinePlayersConn()
	for _, player := range playerArr {
		player.SendBuffPBMsg(uint32(pb.ProtocolManager_LoginKicked), kickOut)
		player.Stop()
	}
	return true
}
